package com.lx.cozeai.biz.impl;


import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.coze.openapi.client.chat.CreateChatReq;
import com.coze.openapi.client.chat.model.ChatEvent;
import com.coze.openapi.client.chat.model.ChatEventType;
import com.coze.openapi.client.connversations.message.model.Message;
import com.coze.openapi.service.auth.TokenAuth;
import com.coze.openapi.service.config.Consts;
import com.coze.openapi.service.service.CozeAPI;

import com.lx.cozeai.biz.AiServise;
import com.lx.cozeai.dao.ChatMessageMapper;
import com.lx.cozeai.entity.ChatMessage;
import io.reactivex.Flowable;
import org.springframework.stereotype.Service;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

import java.io.IOException;
import java.util.Collections;

@Service
public class AiServiseImpl extends ServiceImpl<ChatMessageMapper, ChatMessage> implements AiServise {

    @Override
    public String chat(String msg) {
        return "";
    }

    @Override
//    public String chat(String msg) {
//        // 实现聊天逻辑
//        // Get an access_token through personal access token or oauth.
//        String token = System.getenv("COZE_API_TOKEN");
//        String botID = System.getenv("COZE_BOT_ID");
//        String userID = System.getenv("COZE_USER_ID");
//
//        TokenAuth authCli = new TokenAuth(token);
//
//        // Init the Coze client through the access_token.
//        CozeAPI coze =
//                new CozeAPI.Builder()
//                        .baseURL(Consts.COZE_CN_BASE_URL)
//                        .auth(authCli)
//                        .readTimeout(10000)
//                        .build();
//        ;
//
//        /*
//         * Step one, create chat
//         * Call the coze.chat().stream() method to create a chat. The create method is a streaming
//         * chat and will return a Flowable ChatEvent. Developers should iterate the iterator to get
//         * chat event and handle them.
//         * */
//        CreateChatReq req =
//                CreateChatReq.builder()
//                        .botID(botID)
//                        .userID(userID)
//                        .messages(Collections.singletonList(Message.buildUserQuestionText("What can you do?")))
//                        .build();
//
//        Flowable<ChatEvent> resp = coze.chat().stream(req);
//        resp.blockingForEach(
//                event -> {
//                    if (ChatEventType.CONVERSATION_MESSAGE_DELTA.equals(event.getEvent())) {
//                        return event.getMessage().getContent();
//                    }
//
////                    if (ChatEventType.CONVERSATION_CHAT_COMPLETED.equals(event.getEvent())) {
////                        System.out.println("Token usage:" + event.getChat().getUsage().getTokenCount());
////                    }
//                });
////        System.out.println("done");
//        coze.shutdownExecutor();
//        return null ;
//    }

    public SseEmitter chats(String msg) {
        SseEmitter emitter = new SseEmitter();

        // 初始化 Coze 客户端
        String token = System.getenv("COZE_API_TOKEN");
        String botID = System.getenv("COZE_BOT_ID");
        String userID = System.getenv("COZE_USER_ID");

        TokenAuth authCli = new TokenAuth(token);
        CozeAPI coze = new CozeAPI.Builder()
                .baseURL(Consts.COZE_CN_BASE_URL)
                .auth(authCli)
                .readTimeout(10000)
                .build();

        CreateChatReq req = CreateChatReq.builder()
                .botID(botID)
                .userID(userID)
                .messages(Collections.singletonList(Message.buildUserQuestionText(msg)))
                .build();

        Flowable<ChatEvent> resp = coze.chat().stream(req);

        resp.subscribe(
                event -> {
                    if (ChatEventType.CONVERSATION_MESSAGE_DELTA.equals(event.getEvent())) {
                        try {
                            String content = event.getMessage().getContent();
                            emitter.send(SseEmitter.event().data(content));
                        } catch (IOException e) {
                            emitter.completeWithError(e);
                        }
                    }
                },
                error -> {
                    emitter.completeWithError(error);
                },
                emitter::complete
        );

        return emitter;
    }
}
